package com.hd123.jixia.service;

import com.hd123.jixia.api.PowerNode;
import com.hd123.jixia.api.PowerService;
import com.hd123.jixia.dao.PowerNodeDao;
import com.hd123.jixia.dao.PowerNodeEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;

/**
 * 权限节点服务实现
 *
 * Date: 2021/11/17 17:12
 *
 * @author zhangxin
 * @email zhangxin@hd123.com
 */
@Service
public class PowerServiceImpl implements PowerService {

  @Autowired
  private PowerNodeDao dao;

  @Override
  public PowerNode getById(String id, boolean fetchChildNode) {
    Assert.hasText(id, "id");

    PowerNodeEntity nodeEntity = dao.getById(id);
    if (nodeEntity == null) {
      return null;
    }

    PowerNodeEntity parentNodeEntity = dao.getById(nodeEntity.getParentNodeId());
    List<PowerNodeEntity> childNodeEntities = null;
    if (fetchChildNode) {
      childNodeEntities = dao.getByParentNodeId(nodeEntity.getId());
    }

    return cvt(parentNodeEntity, nodeEntity, childNodeEntities);
  }

  @Override
  public PowerNode getByName(String name, boolean fetchChildNode) {
    Assert.hasText(name, "name");

    PowerNodeEntity nodeEntity = dao.getByName(name);
    if (nodeEntity == null) {
      return null;
    }

    PowerNodeEntity parentNodeEntity = dao.getById(nodeEntity.getParentNodeId());
    List<PowerNodeEntity> childNodeEntities = null;
    if (fetchChildNode) {
      childNodeEntities = dao.getByParentNodeId(nodeEntity.getId());
    }

    return cvt(parentNodeEntity, nodeEntity, childNodeEntities);
  }

  @Override
  public List<PowerNode> listChildNode(String id) {
    Assert.hasText(id, "id");

    PowerNodeEntity nodeEntity = dao.getById(id);
    if (nodeEntity == null) {
      return new ArrayList<>();
    }

    List<PowerNodeEntity> childNodeEntities = dao.getByParentNodeId(nodeEntity.getId());
    List<PowerNode> result = new ArrayList<>();
    childNodeEntities
        .forEach(childNodeEntity -> result.add(cvt(nodeEntity, childNodeEntity, null)));
    return result;
  }

  @Override
  public PowerNode getFetchAllChildNode(String id) {
    PowerNode node = getById(id, true);
    node.getChildNodes().forEach(childNode -> childNode.getChildNodes()
        .add(getFetchAllChildNode(childNode.getNode().getId())));
    return node;
  }

  private PowerNode cvt(PowerNodeEntity parentNodeEntity, PowerNodeEntity nodeEntity,
      List<PowerNodeEntity> childNodeEntities) {
    if (nodeEntity == null) {
      return null;
    }

    PowerNode target = new PowerNode();
    target.setNode(new PowerNode.PowerDefinition(nodeEntity.getId(), nodeEntity.getName()));

    if (parentNodeEntity != null) {
      target.setParentNode(
          new PowerNode.PowerDefinition(parentNodeEntity.getId(), parentNodeEntity.getName()));
    }

    if (childNodeEntities != null) {
      childNodeEntities.forEach(childNodeEntity -> {
        PowerNode childNode = new PowerNode();
        childNode.setNode(
            new PowerNode.PowerDefinition(childNodeEntity.getId(), childNodeEntity.getName()));
        childNode.setParentNode(target.getNode());

        target.getChildNodes().add(childNode);
      });
    }

    return target;
  }

}
